﻿// CommandLineParser.cs
// Copyright (c) 2009 Aleksei Vassiljev

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OracleTools.Core.CommandLine
{
    public class CommandLineParser
    {
        public List<string> Parameters { get; private set; }
        public List<CommandLineArgument> NamedArguments { get; set; }
        public string ParseErrors { get; private set; }

        public string ConsolidatedHelpMessage
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                foreach (CommandLineArgument arg in NamedArguments)
                {
                    string sLine = "-" + arg.Name;
                    if (!string.IsNullOrEmpty(arg.ShortName))
                        sLine += " [-" + arg.ShortName + "]";
                    sLine += " - " + arg.HelpText;
                    sb.AppendLine(sLine);
                }
                return sb.ToString();
            }
        }

        public CommandLineParser()
        {
            this.Parameters = new List<string>();
            this.NamedArguments = new List<CommandLineArgument>();
            this.ParseErrors = "";
        }
        public bool Parse(string[] args)
        {
            if (args.Length == 0) return true;

            string sValue = string.Empty;
            CommandLineArgument argLast = null;
            bool bSearchForValue = false;
            bool bParseResult = true;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i].StartsWith("-") || args[i].StartsWith("/")) // command
                {

                    if (bSearchForValue)
                    {
                        this.ParseErrors += "Value for argument -" + argLast.Name + " was not found";
                        bParseResult = false;
                        bSearchForValue = false;
                    }

                    string sArgument = args[i].Substring(1).ToLower();
                    string sCommand;

                    int nEqPos = sArgument.IndexOf(":");
                    if (nEqPos > -1)
                    {
                        sCommand = sArgument.Substring(0, nEqPos);
                        sValue = sArgument.Substring(nEqPos + 1);
                    }
                    else
                    {
                        sCommand = sArgument;
                        sValue = string.Empty;
                    }

                    foreach (CommandLineArgument arg in this.NamedArguments)
                        if ((sCommand == arg.Name.ToLower()) ||
                            (sCommand == arg.ShortName.ToLower()))
                        {
                            arg.Exists = true;
                            if (arg is ValueArgument)
                            {
                                if (sValue == string.Empty)
                                {
                                    bSearchForValue = true;
                                   //bIsValueFound = false;
                                }
                                else
                                {
                                    (arg as ValueArgument).Value = sValue;
                                    bSearchForValue = false;
                                }
                            }//if (arg is ValueArgument)

                            argLast = arg;

                        }
                }
                else // value
                {
                    if (bSearchForValue)
                    {
                        bSearchForValue = false;

                        if (argLast is ValueArgument)
                        {
                            (argLast as ValueArgument).Value = args[i];
                        }
                        else
                            this.Parameters.Add(args[i]);
                    }
                    else // !bSearchForValue
                    {
                        this.Parameters.Add(args[i]);
                    }
                    
                }
            }//for

            if (bSearchForValue)
            {
                this.ParseErrors += "Value for argument -" + argLast.Name + " was not found";
                bParseResult = false;
                bSearchForValue = false;
            }

            return bParseResult;
        } // public bool Parse

        

    }
}
